-- Node
-- create by zouyb
-- 节点相关工具函数

-- 在node下面查找子节点
-- name使用路径的形式提供，例如：panel/bg1
function findChildByName(node, name)
    local arr = string.explode(name, "/");
    local curr = node;
    for i = 1, #arr do
        if curr == nil then return nil end

        -- 遍历查找
        curr = curr:getChildByName(arr[i]);
    end
    return curr;
end

-- 同findChildByName
function findChildByTag(node, tag)
    local arr = string.explode(tag, "/");
    local curr = node;
    for i = 1, #arr do
        if curr == nil then return nil end

        -- 遍历查找
        curr = curr:getChildByTag(tonumber(arr[i]));
    end
    return curr;
end

-- 获取子控件的路径
function getChildPath(node, child)
    local path = child:getName();

    local count = 1;
    local parent = child:getParent();
    while (parent ~= node) do
        local parentName = parent:getName();
        if parentName == "" then
             parentName = "NoName";
        end
        path = parentName .. "/" .. path;
        
        parent = parent:getParent();
        
        count = count + 1;
        if count > 50 then
            -- 防止无限循环
            break;
        end
    end
    
    return path;
end

-- 封装addTouchEventListener，会自动发布TAEGET_CLICK事件
function AddTouchEventListener(targetNode, f, useBeganEvent)
    local evType = ccui.TouchEventType.ended;
    
    -- 关注began事件来发布TARGET_CLICK事件
    if useBeganEvent then
        evType = ccui.TouchEventType.began;
    end

    local function eventListener(sender, eventType)
        if eventType == evType then  
            EventMgr.fire(event.TARGET_CLICK, { object = sender, });
        end
        
        if f then
            f(sender, eventType);
        end    
    end

    targetNode:addTouchEventListener(eventListener);
    targetNode.touchEventListener = eventListener;
end

-- 替换一个ImageView对象
-- 用于临时解决cocostudio生成的ImageView对象loadTexture图像颠倒的bug
function replaceImageView(from)
    local imageView = ccui.ImageView:create();
    imageView:setAnchorPoint(cc.p(from:getAnchorPoint()));
    imageView:setScaleX(from:getScaleX());
    imageView:setScaleY(from:getScaleY());
    imageView:setRotation(from:getRotationSkewX());
    imageView:setPosition(from:getPosition());
    imageView:setContentSize(from:getContentSize());
    imageView:setName(from:getName());
    imageView:setTouchEnabled(from:isTouchEnabled());

    local parent = from:getParent();
    local zOrder = 0;
    if parent ~= nil then
        local children = parent:getChildren();
        local len = table.getn(children)
        for i = 1, len do
            local child = children[i];
            child:retain();
            if child == from then
                zOrder = i; 
            end
            parent:removeChild(child);
        end

        for i = 1, len do
            local child = children[i];
            parent:addChild(child);
            if i == zOrder then
                parent:addChild(imageView);
            end
            child:release();
        end

        parent:removeChild(from);
    end

    return imageView;
end

-- 替换一个csloader返回的对象树根节点
-- 原来返回的根结点是一个Node，改为Widget
-- 解决在scrollview中滑动事件不响应的问题
function replaceNodeWithWidget(node)
    local widget = ccui.Widget:create();
    widget:setAnchorPoint(cc.p(node:getAnchorPoint()));
    widget:setName(node:getName());
    widget:setPosition(node:getPosition());
    widget:setContentSize(node:getContentSize());
    widget:setScaleX(node:getScaleX());
    widget:setScaleY(node:getScaleY());
    widget:setRotation(node:getRotationSkewX());

    --将Node的孩子挂到widget上
    local children = node:getChildren();
    local len = table.getn(children)
    for i = 0, len-1, 1 do
        local child = children[i + 1];
        child:retain();
        node:removeChild(child);
        widget:addChild(child);
        child:release();
    end

    --从父节点摘除
    local parent = node:getParent();
    local zOrder = node:getLocalZOrder();
    if parent ~= nil then
        parent:addChild(widget, zOrder);
        parent:removeChild(node);
    end

    return widget;
end

-- 新建一个textnode，替换原来的
function replaceTextNode(node) 
    local text = node:clone();
    text:setTextColor(node:getTextColor());
    text:getVirtualRenderer():setAdditionalKerning(node:getVirtualRenderer():getAdditionalKerning());
    text:getVirtualRenderer():setLineHeight(node:getVirtualRenderer():getLineHeight());
    text:getVirtualRenderer():setMaxLineWidth(node:getVirtualRenderer():getMaxLineWidth());
    local outlineColor = node:getOutlineColor();
    local outlineSize = node:getOutlineSize();
    if outlineSize ~= 0 then
        text:enableOutline(outlineColor, outlineSize);
    end    

    local parent = node:getParent();
    local zOrder = 0;
    if parent ~= nil then
        local children = parent:getChildren();
        local len = table.getn(children)
        for i = 1, len do
            local child = children[i];
            child:retain();
            if child == node then
                zOrder = i; 
            end
            parent:removeChild(child);
        end

        for i = 1, len do
            local child = children[i];
            parent:addChild(child);
            if i == zOrder then
                parent:addChild(text);
            end
            child:release();
        end

        parent:removeChild(node);
    end

    return text;
end

------------------------------------------------
-- 设置按钮是否为置灰状态
-- @function setButtionEnabled
-- @param btn 需要设置的按钮组件
-- @param enabled 可用状态
function setButtonEnabled(btn, enabled)
    btn:setBright(enabled);
    btn:setTouchEnabled(enabled);
end

------------------------------------------------
-- 暂停节点
-- @function pauseNode
-- @param node 节点
function pauseNode(node)
    cc.Director:getInstance():getActionManager():pauseTarget(node);

    local children = node:getChildren();
    local len = table.getn(children)
    for i = 1, len do
        local child = children[i];
        pauseNode(child);
    end    
end

------------------------------------------------
-- 继续节点
-- @function resumeNode
-- @param node 节点
function resumeNode(node)
    cc.Director:getInstance():getActionManager():resumeTarget(node);

    local children = node:getChildren();
    local len = table.getn(children)
    for i = 1, len do
        local child = children[i];
        resumeNode(child);
    end    
end

------------------------------------------------
-- 打印可见纹理
function printVisibleTextures(node)
    local function printVisibleImage(node)
        if node:isVisible() then
            if node:getDescription() == "ImageView" then
                print("img:"..node:getTextureName());
            end

            if node ~= nil then
                local children = node:getChildren();
                local len = table.getn(children)
                for i = 1, len do
                    printVisibleImage(children[i]);
                end  
            end
        end                                            
    end
    printVisibleImage(node);
end

-- 判断某个组件是否是按钮
function isButton(node)
    return tolua.type(node) == "ccui.Button";
end

-- 获取一个组件的实际尺寸
function getRealContentSize(node)
    if tolua.type(node) == "ccui.Text" then
        -- 文本控件
        return node:getVirtualRenderer():getContentSize();
    end

    return node:getContentSize();
end


